﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Akso.Authorization;
using Akso.Codes.Dto;
using Akso.Entities;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;

namespace Akso.Codes
{
    [AbpAuthorize(AppPermissions.Pages_BasicDataModule_CodeSettings)]
    public class CodeAppService: AbpZeroTemplateAppServiceBase, ICodeAppService
    {
        private readonly IRepository<CodeEntity, Guid> _codesRepository;
        private readonly IRepository<CodeGroupEntity, Guid> _codeGroupsRepository;
        public CodeAppService(IRepository<CodeEntity, Guid> codesRepository, IRepository<CodeGroupEntity, Guid> codeGroupsRepository)
        {
            _codesRepository = codesRepository;
            _codeGroupsRepository = codeGroupsRepository;
        }

        #region 查询数据
        private IQueryable<CodeEntity> getQuery(GetCodesInput input)
        {
            var query = _codesRepository.GetAll()
                .WhereIf(
                    !input.Filter.IsNullOrWhiteSpace(),
                    t =>
                        t.CodeGroupID.ToString().Contains(input.Filter)
                );
            return query;
        }
        public async Task<ListResultDto<CodeListDto>> GetObjects(GetCodesInput input)
        {
            var query = getQuery(input);
            var dataCount = await query.CountAsync();
            var data = await query.OrderBy(input.Sorting).PageBy(input).ToListAsync();

            return new PagedResultDto<CodeListDto>(
                dataCount,
                data.MapTo<List<CodeListDto>>()
                );
        }
        #endregion

        #region 新增、编辑对象，带权限检查
        /// <summary>
        /// 新增、编辑对象，带权限检查。
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(AppPermissions.Pages_BasicDataModule_Codes_Create, AppPermissions.Pages_BasicDataModule_Codes_Edit)]
        public async Task<CodeEntity> CreateOrUpdateObject(CreateOrUpdateCodeInput input)
        {
            if (input.Code.Id.HasValue)
            {
                return await UpdateObject(input);
            }
            else
            {
                return await CreateObject(input);
            }
        }

        /// <summary>
        /// 新增对象，带权限检查。
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(AppPermissions.Pages_BasicDataModule_Codes_Create)]
        protected virtual async Task<CodeEntity> CreateObject(CreateOrUpdateCodeInput input)
        {
            var o = input.Code.MapTo<CodeEntity>();
            //检查名称是否存在
            
            return await _codesRepository.InsertAsync(o);
        }
        /// <summary>
        /// 编辑对象，带权限检查。
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(AppPermissions.Pages_BasicDataModule_Codes_Edit)]
        protected virtual async Task<CodeEntity> UpdateObject(CreateOrUpdateCodeInput input)
        {
            Debug.Assert(input.Code.Id != null, "input.Classroom.Id should be set.");

            var o = await _codesRepository.GetAsync(input.Code.Id.Value);
            //Update classroom properties
            input.Code.MapTo(o);
            return await _codesRepository.UpdateAsync(o);
        }
        #endregion

        #region 删除数据，带权限检查
        /// <summary>
        /// 删除对象，带权限检查。
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(AppPermissions.Pages_BasicDataModule_Codes_Delete)]
        public async Task DeleteObject(EntityDto<Guid> input)
        {
            var o = await _codesRepository.GetAsync(input.Id);
            await _codesRepository.DeleteAsync(o);
        }
        #endregion

        #region 根据Guid获取数据对象
        /// <summary>
        /// 新增、编辑页面中获取对象，带权限检查。
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(AppPermissions.Pages_BasicDataModule_Codes_Create, AppPermissions.Pages_BasicDataModule_Codes_Edit)]
        public async Task<GetCodeForEditOutput> GetObjectForEdit(NullableIdDto<Guid> input)
        {
            var output = new GetCodeForEditOutput
            {

            };

            if (!input.Id.HasValue)
            {
                //Creating a new object
                output.Code = new CodeEditDto();
            }
            else
            {
                //Editing an existing object
                var existingObject = await _codesRepository.GetAsync(input.Id.Value);

                output.Code = existingObject.MapTo<CodeEditDto>();
            }

            return output;
        }
        #endregion

        /// <summary>
        /// 根据代码组Key获取代码列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ListResultDto<CodeListDto> GetAllCodesByGroupKey(string input)
        {
            var codeGroupEntity = _codeGroupsRepository.GetAll().Where(a => a.CodeGroupKey == input).First();
            return new ListResultDto<CodeListDto>(codeGroupEntity.Codes.ToList().MapTo<List<CodeListDto>>());
        }
    }
}
